home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-06 | 6.3 KB | 241 lines | [TEXT/MPS ] |
- ;*******************************************************************************
- ;
- ; Self-modifying code to allow Gofer to
- ; call Macintosh Toolbox routines.
-
- ; Copyright (c), Kevin Hammond, Glasgow University, 1992/3.
-
- ; The basic routine is:
- ;
- ; TOOLBOXTRAP trap retsize argcount args
-
- ; Only stack-based A-line traps can be called this way,
- ; another mechanism must be used for "normal"
- ; [not in ROM] calls, perhaps through the code
- ; jump table.
-
- ; This will not work on a 68030/040 unless the
- ; instruction pipeline is turned off
- ; (and flushed) before the modified code is
- ; jumped to. This is now done here and the cache
- ; restored afterwards to minimise the performance
- ; penalty in the Toolbox code...
-
- ; Needless to say, be very, very wary of changing this code.
-
-
- ;*******************************************************************************
-
-
-
- ;*******************************************************************************
- ;
- ; This forms part of the Main Code segment
- ;
- ;*******************************************************************************
-
- SEG 'Main'
-
- ;*******************************************************************************
- ;
- ; We need the following external routines
- ;
- ;*******************************************************************************
-
- IMPORT SWAPINSTRUCTIONCACHE
- IMPORT FLUSHINSTRUCTIONCACHE
-
-
- ;*******************************************************************************
- ;
- ; We export these routines and variables.
- ;
- ;*******************************************************************************
-
- EXPORT TOOLBOXTRAP
- EXPORT trapreg_d0
- EXPORT trapreg_d1
- EXPORT trapreg_a0
- EXPORT trapreg_a1
-
- ;*******************************************************************************
- ;
- ; Buffers for the trap registers
- ;
- ;*******************************************************************************
-
- trapreg_d0 PROC EXPORT
- DC.L $0
- trapreg_d1 PROC EXPORT
- DC.L $0
- trapreg_a0 PROC EXPORT
- DC.L $0
- trapreg_a1 PROC EXPORT
- DC.L $0
-
- ;*******************************************************************************
- ;
- ; Disable the instruction cache and record the old setting
- ;
- ;*******************************************************************************
-
-
- instrcache PROC EXPORT
- DC.W $0 ; Buffer to record the old ICache setting
-
-
- DisableICache PROC EXPORT ; Disable the instruction cache
- JSR FLUSHINSTRUCTIONCACHE ; Just in case our loop doesn't fool the cache
- MOVE.W #0,-(SP) ; Result word
- MOVE.W #0,-(SP) ; Disable the Instruction cache
- JSR SWAPINSTRUCTIONCACHE ; ...
- MOVE.L instrcache,A0 ; Save the previous setting
- MOVE.W (SP)+,(A0) ; ...
- RTS
-
-
- ;*******************************************************************************
- ;
- ; Restore the previous setting of the instruction cache
- ;
- ;*******************************************************************************
-
- RestoreICache PROC EXPORT ; Reset the I/D caches
- MOVE.L A0,-(SP) ; push continuation
- MOVE.W #0,-(SP) ; Result word
- MOVE.L instrcache,A0 ; Reset the Instruction cache
- MOVE.W (A0),-(SP) ; ...
- BSR SwapInstructionCache ; ...
- ADDQ.L #2,SP ; Ignore the result
- MOVE.L trapreg_d0,D0 ; Set registers for register-based
- MOVE.L trapreg_d1,D1 ; routines or packages
- MOVE.L trapreg_a0,A0 ; ...
- MOVE.L trapreg_a1,A1 ; ...
- RTS
-
-
-
- ;*******************************************************************************
- ;
- ; Trap with short result
- ;
- ;*******************************************************************************
-
- trbuf PROC EXPORT ; Record the trap word.
- TRAP #$0 ; Dummy trap word
- CLR.L D0 ; Clear the result
- MOVE.W (SP),D0 ; Save the short result
- MOVE.L D0,$12(A6) ; Record the dummy result
- UNLK A6 ; Unlink the frame pointer
- MOVE.L (SP)+,A0 ; Save the return address
- LEA $0A(SP),SP ; Pop the arguments
- JMP (A0) ; And return
-
- DC.B $85, 'trbuf'
- DC.W 0
- ENDP ; trbuf
-
-
- ;*******************************************************************************
- ;
- ; Trap with longword result
- ;
- ;*******************************************************************************
-
-
- trbuflr PROC EXPORT ; Record the trap word.
- TRAP #$0 ; Dummy trap word
- MOVE.L (SP),D0 ; Save the result
- MOVE.L D0,$12(A6) ; Record the dummy result
- UNLK A6 ; Unlink the frame pointer
- MOVE.L (SP)+,A0 ; Save the return address
- LEA $0A(SP),SP ; Pop the arguments
- JMP (A0) ; And return
-
- DC.B $87, 'trbuflr'
- DC.W 0
- ENDP ; trbuflr
-
-
-
-
- ;*******************************************************************************
- ;
- ; Trap with no result/result in d0
- ;
- ;*******************************************************************************
-
-
- trbufnr PROC EXPORT ; Record the trap word.
- TRAP #$0 ; Dummy trap word
- MOVE.L D0,$12(A6) ; Record a dummy result
- ; or the correct result for register-based routines.
- UNLK A6 ; Unlink the frame pointer
- MOVE.L (SP)+,A0 ; Save the return address
- LEA $0A(SP),SP ; Pop the arguments
- JMP (A0) ; And return
-
- DC.B $87, 'trbufnr'
- DC.W 0
- ENDP ; trbufnr
-
-
-
- ;*******************************************************************************
- ;
- ; Call a Toolbox routine.
- ;
- ;*******************************************************************************
-
-
- TOOLBOXTRAP PROC EXPORT
-
- LINK A6,#0 ; Link for 100% Pascal compatibility
-
- BSR DisableICache ; Disable the instruction cache
-
- MOVE.W $0E(A6),A0
-
-
- MOVE.W $0C(A6),D1 ; Arg Count -- 128 maximum
- MOVEQ #0,D0 ; Arg Index -- count UP, since trap args are reversed!
-
- MOVE.L $08(A6),A1 ; Parameter buffer
-
- CMP.W #0,A0 ; Set up the trap and return parameters
- BEQ.B noresult ; according to the size of the result
- CMP.W #1,A0
- BEQ.B shortresult
-
- longresult LEA trbuflr,A0 ; Trap Location
- MOVE.W $10(A6),(A0) ; Set the Trap
- MOVE.L #0,-(SP) ; Longword Result
- JMP traploop
-
- shortresult LEA trbuf,A0 ; Trap Location
- MOVE.W $10(A6),(A0) ; Set the Trap
- MOVE.W #0,-(SP) ; Shortword Result
- JMP traploop
-
- noresult LEA trbufnr,A0 ; Trap Location
- MOVE.W $10(A6),(A0) ; Set the Trap
-
-
- traploop CMPI.W #0,D1 ; when no more args
- BEQ RestoreICache ; do the trap -- this branch is really
- ; a call with nominated continuation in A0!
-
- MOVE.W (A1,D0),-(SP) ; push the arg
-
- SUBQ.W #1,D1 ; Dec. arg count
- ADDQ.W #2,D0 ; post-increment the index as a BYTE counter
-
- JMP traploop ; and repeat.
-
- DC.B $8b, 'ToolboxTrap'
- DC.W 0
- ENDP ; ToolboxTrap
-
- END
-
-